home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / Macintosh Sample Code / SC.020.Transformer / Transformer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-30  |  5.8 KB  |  226 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    BitMap Transformer
  6. #
  7. #    Transformer.c    -    C Source
  8. #
  9. #    Copyright © 1989 Apple Computer, Inc.
  10. #    All rights reserved.
  11. #
  12. #    Versions:
  13. #                1.0                         10/89
  14. #
  15. #    Components:
  16. #                MTransformer.p                October 1, 1989
  17. #                UTransformer.p                October 1, 1989
  18. #                UTransformer.inc1.p         October 1, 1989
  19. #                Transformer.c                October 1, 1989
  20. #                Transformer.r                October 1, 1989
  21. #                Transformer.MAMake            October 1, 1989
  22. #                ProjInit                    October 1, 1989
  23. #                The BitMap Transmogrifier    October 1, 1989
  24. #
  25. #    Requirements:
  26. #                MacApp® 2.0ß9                July 10, 1989
  27. #
  28. # "Transformers" is a sample program that demonstrates how to translate,
  29. # rotate, and scale bitmaps. It uses a MacApp shell to open file, open
  30. # windows, and handle menus, but the core routine is written in vanilla C.
  31. #
  32. ------------------------------------------------------------------------------*/
  33.  
  34. #include <Types.h>
  35. #include <QuickDraw.h>
  36. #include <Files.h>
  37. #include <Memory.h>
  38. #include <ToolUtils.h>
  39. #include <CursorCtl.h>
  40.  
  41. #define NIL        0L
  42. #define    PI        (3.14159265358979323846)
  43.  
  44.  
  45. //
  46. // pascal void GetThePicture( short aRefNum, Ptr data );
  47. //
  48. // pascal void DoTransform(BitMap *sourceBM, BitMap *destBM, Point center, Point destination,
  49. //                 short rotation, extended sx, extended sy);
  50. //
  51.  
  52. extern pascal void FailOSErr( short );
  53. extern pascal void FailNIL( Ptr );
  54. extern pascal void ClearBitMap( BitMap *aBitMap );
  55. extern pascal void BusyActivate( Boolean );
  56.  
  57. pascal void GetThePicture( short aRefNum, Ptr data)
  58. {
  59.     long        srcSize;
  60.     Ptr            srcPtr, destPtr, lastDstPtr, saveSrcPtr;
  61.     short        scanLine;
  62.  
  63.     FailOSErr(SetFPos(aRefNum, fsFromStart, 512L));
  64.     FailOSErr(GetEOF(aRefNum, &srcSize));
  65.     srcSize = srcSize - 512; 
  66.     FailNIL(srcPtr = NewPtr(srcSize));
  67.     FailOSErr(FSRead(aRefNum, &srcSize, srcPtr));
  68.  
  69.     saveSrcPtr = srcPtr;
  70.     destPtr = data;       
  71.     lastDstPtr = destPtr;
  72.  
  73.     for ( scanLine = 1; scanLine < 720; scanLine++ ) { 
  74.          UnpackBits(&srcPtr, &destPtr, 72); 
  75.     };
  76.     
  77.     DisposPtr(saveSrcPtr);
  78. }
  79.  
  80. // The following routines that are compiled out are functional, but they are not
  81. // optimized for speed. They are included here just so that you can see a sample
  82. // that is a bit clearer than the optimized routine that appears later.
  83.  
  84. #if false
  85. Boolean myGetPixel(bm, x, y)
  86. BitMap *bm;
  87. short x, y;
  88. {
  89.     Boolean result;
  90.     Point    tempPt;
  91.     long    *longPtr;
  92.         
  93.     tempPt.v = y;
  94.     tempPt.h = x;
  95.     if (PtInRect(tempPt, &(bm->bounds))) {
  96.         longPtr = (long *) (bm->baseAddr + ((long)y * bm->rowBytes) + (x / 32) * 4);
  97.         result = 1 & ((*longPtr) >> (31 - (x % 32)));
  98.     } else {
  99.         result = false;  /* return white */
  100.     }
  101.     return (result);
  102. }
  103.  
  104.  
  105. void mySetPixel(bm, x, y)
  106. BitMap *bm;
  107. short x, y;
  108. {
  109.     Point    tempPt;
  110.     long    *longPtr;
  111.         
  112.     tempPt.v = y;
  113.     tempPt.h = x;
  114.     if (PtInRect(tempPt, &(bm->bounds))) {
  115.         longPtr = (long *) (bm->baseAddr + ((long)y * bm->rowBytes) + (x / 32) * 4);
  116.         *longPtr |= (0x80000000 >> (x % 32));
  117.     }
  118. }
  119.  
  120.  
  121. pascal void DoTransform(BitMap *sourceBM, BitMap *destBM, Point center, Point destination,
  122.                 short rotation, extended sx, extended sy)
  123. {
  124.     short        i;
  125.     short        j;
  126.     short        newX, newY;
  127.     Boolean        isSet;
  128.     long        *longPtr;
  129.  
  130.     short        width = destBM->bounds.right;
  131.     short        height = destBM->bounds.bottom;
  132.  
  133.     extended    r11 =  (1/sx) * cos(rotation * (PI/180));
  134.     extended    r12 = -(1/sx) * sin(rotation * (PI/180));
  135.     extended    r21 =  (1/sy) * sin(rotation * (PI/180));
  136.     extended    r22 =  (1/sy) * cos(rotation * (PI/180));
  137.     
  138.     extended    tx    = -destination.h*r11 - destination.v*r12 + center.h;
  139.     extended    ty    = -destination.h*r21 - destination.v*r22 + center.v;
  140.  
  141.     
  142.     BusyActivate(false);
  143.     Show_Cursor(HIDDEN_CURSOR);
  144.     ClearBitMap(destBM);
  145.     
  146.     for ( j = 0; j < height; j++ ) {
  147.         SpinCursor(4);
  148.         for ( i = 0; i < width; i++ ) {
  149.         
  150.             newX = i*r11 + j*r21 + tx + .5;
  151.             newY = i*r12 + j*r22 + ty + .5;
  152.             
  153.             isSet = myGetPixel(sourceBM, newX, newY);
  154.             if (isSet) mySetPixel(destBM, i, j);
  155.         }
  156.     }
  157.     BusyActivate(true);
  158. }
  159. #endif
  160.  
  161.  
  162. // This version of DoTransform() is optimized for speed. It's not as fast
  163. // as it could possibly be, but it's fair. Neither is it very readable...
  164.  
  165. pascal void DoTransform(BitMap *sourceBM, BitMap *destBM, Point center, Point destination,
  166.                 short rotation, extended sx, extended sy)
  167. {
  168.     register short    i;
  169.     register short    j;
  170.     short        newX;
  171.     short        newY;
  172.     long        *longPtr;
  173.  
  174.     short        width        = destBM->bounds.right;
  175.     short        height        = destBM->bounds.bottom;
  176.     Rect        *tPtr        = &(sourceBM->bounds);
  177.     Ptr            sourceBase    = sourceBM->baseAddr;
  178.     Ptr            destBase    = destBM->baseAddr;
  179.     Ptr            destBase2;
  180.     short        sourceRB    = sourceBM->rowBytes;
  181.     short        destRB        = destBM->rowBytes;
  182.  
  183.     extended    rotInRads    = rotation * (PI/180);
  184.     
  185.     extended    r11            =  (1/sx) * cos(rotInRads);
  186.     extended    r12            = -(1/sx) * sin(rotInRads);
  187.     extended    r21            =  (1/sy) * sin(rotInRads);
  188.     extended    r22            =  (1/sy) * cos(rotInRads);
  189.     
  190.     extended    tx            = -destination.h*r11 - destination.v*r12 + center.h + .5;
  191.     extended    ty            = -destination.h*r21 - destination.v*r22 + center.v + .5;
  192.     
  193.     extended    interX;        /* intermediate result */
  194.     extended    interY;        /* intermediate result */
  195.     
  196.     BusyActivate(false);
  197.     Show_Cursor(HIDDEN_CURSOR);
  198.     ClearBitMap(destBM);
  199.         
  200.     for ( j = 0; j < height; j++ ) {
  201.         SpinCursor(4);        // spin my gears once every 32/4 times through this loop
  202.         destBase2 = destBase + (long) j * destRB;
  203.         interX = j*r12 + tx;
  204.         interY = j*r22 + ty;
  205.         for ( i = 0; i < width; i++ ) {
  206.  
  207.             newX = i*r11 + interX;
  208.             newY = i*r21 + interY;
  209.             
  210.             if ( (newX < tPtr->left) || (newX >= tPtr->right) ||
  211.                  (newY < tPtr->top)  || (newY >= tPtr->bottom) ) {
  212.                 continue;
  213.             } else {
  214.                 longPtr = (long *) (sourceBase + ((long)newY * sourceRB) + (newX / 32) * 4);
  215.                 if (!(1 & ((*longPtr) >> (31 - (newX % 32)))))
  216.                     continue;
  217.             }
  218.             
  219.             longPtr = (long *) (destBase2 + (i / 32) * 4);
  220.             *longPtr |= ( (unsigned long) 0x80000000 >> (i % 32));
  221.         }
  222.     }
  223.     BusyActivate(true);
  224. }
  225.  
  226.